﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Telerik.Web.UI;
using System.Web.UI;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Xml;
using System.Web.Caching;
using System.Collections;
using log4net;


/// <summary>g
/// Summary description for ComboBoxUtil
/// </summary>
public class ControlUtil
{
    protected static readonly ILog log = LogManager.GetLogger(typeof(DBDataContext));
    public ControlUtil()
    {

    }
    #region Get List for combo
    public static List<ComboItem> GetComboOfCodeDetail(string codedetail, bool isCache = true)
    {
        string cacheName = "CodeDetail" + codedetail;
        List<ComboItem> list = new List<ComboItem>();
        if (CacheUtil.GetCache(cacheName) != null && isCache)
        {
            list = (List<ComboItem>)CacheUtil.GetCache(cacheName);
        }
        else
        {
            DBDataContext db = new DBDataContext();
            list = (from c in db.CodeDetails
                    where c.CMCode == codedetail
                    orderby c.Ordinal, c.CMCode
                    select new ComboItem
                    {
                        Text = c.CDName,
                        Value = c.CDCode
                    }).ToList();
        }
        return list;
    }
    public static List<ComboItem> GetUserListInOrderPerson()
    {
        try
        {
            List<ComboItem> list = new List<ComboItem>();
            List<int> listroleid = new List<int>();
            listroleid.Add(19);
            listroleid.Add(24);
            list = GetUserListByRole(listroleid);
            return list;
        }
        catch
        { 
            return new List<ComboItem>();
        }
    }
    public static List<ComboItem> GetUserListByRole(List<int> Listroleid)
    {
        List<ComboItem> list = new List<ComboItem>();
        DBDataContext db = new DBDataContext();
        list = (from c in db.UserRoles
                where Listroleid.Contains(c.RoleID)
                orderby c.UserName
                select new ComboItem
                {
                    Text = c.UserName,
                    Value = c.UserName
                }).ToList();
        return list;
    }

    public static List<ComboItem> GetComboItem<T>(bool isCache = true, bool isRegionLv2 = false)
    {
        DBDataContext db = new DBDataContext();
        List<ComboItem> list = new List<ComboItem>();
        string tableName = typeof(T).Name;
        string cacheName = "";//"Combo" + tableName;
        string UserName = HttpContext.Current.Session["UserName"].ToString();
        if (tableName.ToLower() == "region")
        {
            cacheName = "Combo" + tableName + "_" + UserName;
            if (isRegionLv2)
            {
                cacheName += "_RegionLv2";
            }
        }
        else
        {
            cacheName = "Combo" + tableName;
        }
        if (CacheUtil.GetCache(cacheName) != null && isCache)
        {
            list = (List<ComboItem>)CacheUtil.GetCache(cacheName);
            return list;
        }
        else
        {
            bool isParent = typeof(T).GetProperty("ParentID") != null;
            bool isCode = typeof(T).GetProperty(tableName + "Code") != null;
            
            string parentStr = isParent ? "CAST(ParentID AS varchar(20)) AS ParentId" : " '' AS ParentId ";
            string codeStr = isCode ? tableName + "Code AS Value" : "CAST(ID AS varchar(20)) AS Value";
            string textStr = tableName + "Name AS Text";
            if (tableName.ToLower() == "stockin")
            {
                textStr = tableName + "Code AS Text";
            }
            string sql = "";// "SELECT " + codeStr + "," + textStr + "," + parentStr + " FROM [" + tableName + "] WHERE Status='" + ObjectStatus.Active + "'";
            if (tableName.ToLower() == "region")
            {
                if(!isRegionLv2)
                {
                    sql = ";WITH RegionTemp(RegionID, RegionName, ParentID) AS"
                        + "("
                        + "     SELECT A.ID,A.RegionName, A.ParentID"
                        + "     FROM Region A (Nolock)"
                        + "     INNER JOIN RegionUser B ON A.ID = B.RegionID"
                        + "     WHERE B.UserName= '" + UserName + "'"
                        + "     AND A.[Status]='A'"
                        + "     AND B.[Status]='A'"
                        + "     UNION ALL"
                        + "     SELECT C.ID,C.RegionName, C.ParentID"
                        + "     FROM Region C (Nolock)"
                        + "     INNER JOIN RegionTemp D ON C.ParentID = D.RegionID"
                        + "     WHERE C.Status='A'"
                        + ")"
                        + "   SELECT CAST(T.RegionID AS varchar(20)) AS Value, T.RegionName AS Text, CAST(T.ParentID AS varchar(20)) AS ParentId"
                        + "   FROM RegionTemp T";
                }
                else
                {
                    sql = ";WITH RegionTemp(RegionID, RegionName, ParentID) AS"
                    + "("
                    + "     SELECT A.ID,A.RegionName, A.ParentID"
                    + "     FROM Region A (Nolock)"
                    + "     INNER JOIN RegionUser B ON A.ID = B.RegionID"
                    + "     WHERE B.UserName= '" + UserName + "'"
                    + "     AND A.[Status]='A'"
                    + "     AND B.[Status]='A'"
                    + "     UNION ALL"
                    + "     SELECT C.ID,C.RegionName, C.ParentID"
                    + "     FROM Region C (Nolock)"
                    + "     INNER JOIN RegionTemp D ON C.ParentID = D.RegionID"
                    + "     WHERE C.Status='A'"
                    + "     AND C.RegionLevel<=2"
                    + ")"
                    + "   SELECT CAST(T.RegionID AS varchar(20)) AS Value, T.RegionName AS Text, CAST(T.ParentID AS varchar(20)) AS ParentId"
                    + "   FROM RegionTemp T";
                }
            }
            else
            {
                sql = "SELECT " + codeStr + "," + textStr + "," + parentStr + " FROM [" + tableName + "] WHERE Status='" + ObjectStatus.Active + "'";
            }
            if (tableName.ToLower() == "stockin")
            {
                //sql += "OR Status='N'";
                sql = "SELECT " + codeStr + "," + textStr + "," + parentStr + " FROM [" + tableName + "] WHERE Status='N'";
            }
            list = db.ExecuteQuery<ComboItem>(sql).ToList();

            //Validation list
            List<ComboItem> l2 = new List<ComboItem>();
            foreach (var item in list)
            {
                ComboItem i = new ComboItem();
                i.Text = item.Text;
                i.Value = item.Value;
                if (item.ParentId.Length != 0 && item.ParentId != "0")
                {
                    i.ParentId = item.ParentId;
                }
                l2.Add(i);
            }
            return l2;
        }


    }
    #endregion
    #region ForCombo

    //PUBLIC
    public static void ForCombo<T>(Control control, String header = "", bool isCache = true)
    {
        List<ComboItem> list = GetComboItem<T>(isCache);
        ForCombo(control, list, header);
    }
    public static void ForComboByCode<T>(Control control, String code, String header = "", bool isCache = true)
    {

        List<ComboItem> list = GetComboItem<T>(isCache);
        list = list.Where(x => x.ParentId == code).ToList();

        if (control.GetType() == typeof(HtmlSelect))
        {
            HtmlSelect combo = (HtmlSelect)control;
            ForCombo(combo, list, header);
        }
        else if (control.GetType() == typeof(DropDownList))
        {
            DropDownList combo = (DropDownList)control;
            ForCombo(combo, list, header);
        }
        else if (control.GetType() == typeof(RadComboBox))
        {
            RadComboBox combo = (RadComboBox)control;
            ForCombo(combo, list, header);
        }
    }
    public static void ForComboHierarchyByCode<T>(RadComboBox rcbCategory, String code, String header = "", bool isCache = true)
    {
        List<ComboItem> list = GetComboItem<T>(isCache);
        list = list.Where(x => x.ParentId == code).ToList();

        if (list.Count > 0)
        {
            ComboItem comboItemFirst = list.FirstOrDefault();

            if (comboItemFirst != null && header.Length == 0)
            {
                header = comboItemFirst.Text;
            }
            list = list.Where(x => x.Value != code).ToList();
        }
        ForComboHierarchy(rcbCategory, list, header);

    }


    public static void ForComboHierarchy<T>(RadComboBox rcbCategory, String header = "", bool isCache = true, bool isRegionLv2 = false)
    {
        List<ComboItem> list = GetComboItem<T>(isCache, isRegionLv2);
        ForComboHierarchy(rcbCategory, list, header);
    }
    public static void ForComboHierarchyAndID<T>(RadComboBox rcb, String header = "", bool isCache = true)
    {
        List<ComboItem> list = GetComboItem<T>(isCache);
        ForComboHierarchyAndID(rcb, list, header);
    }
    public static void ForComboByCodeDetail(Control control, String codedetail, String header = "", bool isCache = true)
    {
        List<ComboItem> list = GetComboOfCodeDetail(codedetail);
        if (control.GetType() == typeof(HtmlSelect))
        {
            HtmlSelect combo = (HtmlSelect)control;
            ForCombo(combo, list, header);
        }
        else if (control.GetType() == typeof(DropDownList))
        {
            DropDownList combo = (DropDownList)control;
            ForCombo(combo, list, header);
        }
        else if (control.GetType() == typeof(RadComboBox))
        {
            RadComboBox combo = (RadComboBox)control;
            ForCombo(combo, list, header);
        }
    }


    public static void ForComboHierarchySelectedValue(RadComboBox rcb, String selectedValue)
    {
        RadTreeView tvCategory = (RadTreeView)rcb.Items[0].FindControl("tvHierarchy");
        if (tvCategory != null)
        {
            RadTreeNode rtn = tvCategory.FindNodeByValue(selectedValue);
            if (rtn != null)
            {
                tvCategory.FindNodeByValue(selectedValue).ExpandParentNodes();
                rtn.Selected = true;
                if (tvCategory.OnClientNodeClicking == "rcbHierarchyClientClickingByValue")
                {
                    rcb.Items[0].Text = rtn.Value;
                }
                else
                {
                    rcb.Items[0].Text = rtn.Text;
                }

            }
        }
    }
    public static string ForComboHierarchySelectedValue(RadComboBox rcb)
    {
        RadTreeView tvRegionHierarchy = (RadTreeView)rcb.Items[0].FindControl("tvHierarchy");
        if (tvRegionHierarchy.SelectedNode != null)
        {
            return tvRegionHierarchy.SelectedNode.Value;
        }
        return String.Empty;
    }

    //PRIVATE
    public static void ForCombo(Control control, List<ComboItem> list, String header = "")
    {
        if (control.GetType() == typeof(HtmlSelect))
        {
            HtmlSelect combo = (HtmlSelect)control;
            ForCombo(combo, list, header);
        }
        else if (control.GetType() == typeof(DropDownList))
        {
            DropDownList combo = (DropDownList)control;
            ForCombo(combo, list, header);
        }
        else if (control.GetType() == typeof(RadComboBox))
        {
            RadComboBox combo = (RadComboBox)control;
            ForCombo(combo, list, header);
        }

    }
    private static void ForCombo(HtmlSelect combo, List<ComboItem> list, String header = "")
    {
        if (header.Length != 0 && list.Count > 0)
        {
            list.Insert(0, new ComboItem(header, ""));
        }
        combo.DataSource = list;
        combo.DataTextField = "Text";
        combo.DataValueField = "Value";
        combo.DataBind();
    }
    private static void ForCombo(DropDownList combo, List<ComboItem> list, String header = "")
    {
        if (header.Length != 0 && list.Count > 0)
        {
            list.Insert(0, new ComboItem(header, ""));
        }
        combo.DataSource = list;
        combo.DataTextField = "Text";
        combo.DataValueField = "Value";
        combo.DataBind();
    }
    private static void ForCombo(RadComboBox combo, List<ComboItem> list, String header = "")
    {
        if (header.Length != 0 && list.Count > 0)
        {
            list.Insert(0, new ComboItem(header, ""));
        }
        combo.DataSource = list;
        combo.DataTextField = "Text";
        combo.DataValueField = "Value";
        combo.ClearSelection();
        combo.DataBind();
    }
    public static void ForComboHierarchy(RadComboBox rcbCategory, List<ComboItem> list, String header = "")
    {
        foreach (ComboItem item in list)
        {
            if (!list.Select(x => x.Value).Contains(item.ParentId))
            {
                item.ParentId = null;
            }
        }


        if (header.Length != 0)
        {
            ComboItem bank = new ComboItem(header, "", null);
            list.Insert(0, bank);
        }
        rcbCategory.Items.Add(new RadComboBoxItem(header));
        RadTreeView tvCategory = (RadTreeView)rcbCategory.Items[0].FindControl("tvHierarchy");
        tvCategory.DataTextField = "Text";
        tvCategory.DataValueField = "Value";
        tvCategory.DataFieldParentID = "ParentId";
        tvCategory.DataFieldID = "Value";
        tvCategory.DataSource = list;
        tvCategory.DataBind();
        tvCategory.CollapseAllNodes();
        if (list.Count > 0)
            tvCategory.Nodes[0].Selected = true;

        if (header.Length != 0)
        {
            rcbCategory.Text = header;
            rcbCategory.Items[0].Text = header;
        }
    }
    private static void ForComboHierarchyAndID(RadComboBox rcbCategory, List<ComboItem> list, String header = "")
    {
        if (header.Length != 0)
        {
            ComboItem bank = new ComboItem(header, "");
            list.Insert(0, bank);
        }
        rcbCategory.DataSource = list;
        rcbCategory.DataTextField = "Text";
        rcbCategory.DataValueField = "Value";
        rcbCategory.DataBind();
        //rcbCategory.Items.Add(new RadComboBoxItem(header));
        //RadTreeView tvCategory = (RadTreeView)rcbCategory.Items[0].FindControl("tvHierarchy");
        //tvCategory.DataTextField = "Text";
        //tvCategory.DataValueField = "Value";
        //tvCategory.DataFieldParentID = "ParentId";
        //tvCategory.DataFieldID = "Value";
        //tvCategory.DataSource = list;
        //tvCategory.DataBind();
        //tvCategory.CollapseAllNodes();
        //tvCategory.Nodes[0].Selected = true;

        if (header.Length != 0)
        {
            rcbCategory.Text = header;
        }
    }

    

    #endregion
    #region ForListBox



    public static List<ComboItem> ForListBoxHierarchy<T>(RadTreeView rtv, bool isCache = true)
    {
        rtv.CheckBoxes = true;
        rtv.CheckChildNodes = true;
        List<ComboItem> list = GetComboItem<T>(isCache);
        rtv.DataFieldParentID = "ParentId";
        rtv.DataFieldID = "Value";
        rtv.DataValueField = "Value";
        rtv.DataTextField = "Text";
        rtv.DataSource = list;
        rtv.DataBind();
        rtv.BorderColor = System.Drawing.Color.Black;
        rtv.BorderStyle = BorderStyle.Solid;
        rtv.BorderWidth = 1;
        return list;
    }
    public static void ForListBoxHierarchySelectedValue(RadTreeView rtv, List<String> selectedValues)
    {
        rtv.UncheckAllNodes();
        rtv.CollapseAllNodes();
        foreach (String item in selectedValues)
        {
            RadTreeNode node = rtv.FindNodeByValue(item);
            if (node != null)
            {
                node.Checked = true;
                RadTreeViewUnCheckParent(node);
                node.ExpandParentNodes();
            }
        }
    }
    private static void RadTreeViewUnCheckParent(RadTreeNode node)
    {
        //Nếu có 1 node con unCheck thì node cha Uncheck
        if (node.Parent.GetType() == typeof(RadTreeNode))
        {
            RadTreeNode parent = (RadTreeNode)node.Parent;
            bool kt = true;
            foreach (RadTreeNode child in parent.Nodes)
            {
                if (!child.Checked)
                {
                    kt = false;
                    break;
                }
            }
            parent.Checked = kt;
        }
    }
    public static List<ComboItem> ForListBox<T>(RadTreeList tv, bool isCache = true)
    {
        List<ComboItem> list = GetComboItem<T>(isCache);
        return list;
    }
    public static List<ComboItem> ForListBoxByParentCode<T>(RadTreeList tv, String parentCode, bool isCache = true)
    {
        List<ComboItem> list = GetComboItem<T>(isCache);
        list = list.Where(x => x.ParentId == parentCode).ToList();
        tv.ParentDataKeyNames = new string[] { "ParentId" };
        tv.DataKeyNames = new string[] { "Value" };
        tv.DataSource = list;
        return list;
    }





    #endregion
    #region Dialog
    public static void ShowConfirmDialog(Panel pn, string literalId, string message)
    {
        Label ltr = pn.FindControl(literalId) as Label;
        if (ltr != null)
        {
            ltr.Text = message;
        }
        pn.Visible = true;
    }
    #endregion

    public static void Log(object message)
    {
        log.Info(message);
    }

    public static void LogError(object message)
    {
        log.Error(message);
    }

    public static IEnumerable<Control> GetAllControl(Control control, Type type)
    {
        var controls = control.Controls.Cast<Control>();
        return controls.SelectMany(ctrl => GetAllControl(ctrl, type)).Concat(controls).Where(c => c.GetType() == type);
    }


   

}
public class ComboItem
{
    public string Text { get; set; }
    public string Value { get; set; }
    public string ParentId { get; set; }
    public int? Level { get; set; }
    public ComboItem()
    {
    }
    public ComboItem(string text, string value)
    {
        Text = text;
        Value = value;

    }
    public ComboItem(string text, string value, string parentId = "")
    {
        Text = text;
        Value = value;
        ParentId = parentId;
    }

}
public class ComboVendor
{
    public ComboVendor()
    {
    }
    string vendorCode = "";

    public string VendorCode
    {
        get { return vendorCode; }
        set { vendorCode = value; }
    }

    string vendorName = "";

    public string VendorName
    {
        get { return vendorName; }
        set { vendorName = value; }
    }
    string both = "";

    public string Both
    {
        get { return both; }
        set { both = value; }
    }

}
public class TreeViewItem
{
    public string Text { get; set; }
    public string Value { get; set; }
    public string ParentId { get; set; }
    public int? Level { get; set; }
    public bool Check { get; set; }
    public TreeViewItem()
    {
    }
    public TreeViewItem(string text, string value, bool check)
    {
        Text = text;
        Value = value;
        Check = check;
    }
}

public class CacheUtil
{
    private static Cache cache = HttpContext.Current.Cache;
    public static void InsertCache(string cacheName, object value, int timeSpan = 10, bool force = false)
    {
        if (force == false)
        {
            if (cache[cacheName] != null)
            {
                cache.Insert(cacheName, value, null, DateTime.MaxValue, TimeSpan.FromMinutes(timeSpan));
            }
        }
        else
        {
            cache.Insert(cacheName, value, null, DateTime.MaxValue, TimeSpan.FromMinutes(timeSpan));
        }
    }

    public static object GetCache(string cacheName)
    {
        object result = cache[cacheName];
        if (result != null)
        {
            return result;
        }
        else
        {
            result = null;
        }
        return result;
    }
    public static void ClearCache(string cacheName)
    {
        cache.Remove(cacheName);
    }
    public static void ClearAllCache()
    {
        List<string> keys = new List<string>();
        IDictionaryEnumerator enumerator = cache.GetEnumerator();
        while (enumerator.MoveNext())
        {
            keys.Add(enumerator.Key.ToString());
        }
        for (int i = 0; i < keys.Count; i++)
        {
            cache.Remove(keys[i]);
        }
    }
}
public enum CodeDetailName
{
    AgeGroup,
    Bank,
    BillingType,
    BonusType,
    CategoryGroup,
    Color,
    CompanyType,
    ContractType,
    Currency,
    CustomerGroup,
    CustomerRegion,
    DataType,
    Department,
    EmployeeGroup,
    EmployeeType,
    Frequency,
    FunctionType,
    HierarchyLevel,
    HoildayType,
    HolidayType,
    IncentiveType,
    OrganizationHierarchiesLevel,
    WarehouseTypes,
    PLTargetType,
    IncentiveFormula,
    JobTitle,
    ObjectStatus,
    PaymentTerm,
    PaymentType,
    ProductRequestStatus,
    RegionLevel,
    RequestBy,
    SalaryType,
    SalesGroup,
    SalesInvoiceStatus,
    SalesInvoiceType,
    Status,
    StoreType,
    TargetType,
    TaxType,
    TimeCheckingFormula,
    TitleComputerSkill,
    TitleGender,
    TitleHighestEduLevel,
    UserType,
    Vat,
    VendorType,
    WarehouseGroup,
    WarehouseLocType,
    WarehouseType,
    Warehouse,
    ManageUserB1,
    OrientedProcess,
    RequestStatus
}